import { ipcMain, dialog, app, shell, BrowserWindow } from 'electron';
import { DatabaseManager } from '../../../core/database/database';
import { PhotoRepository } from '../../../core/database/repositories/photo-repository';
import { FileScanner } from '../../../core/scanner/file-scanner';
import { ThumbnailGenerator } from '../../../core/thumbnail/generator';
import { MetadataExtractor } from '../../../core/metadata/extractor';
import path from 'path';
import fs from 'fs/promises';
import { createHash } from 'crypto';

/**
 * IPC 处理器管理类
 * 负责注册和管理所有主进程与渲染进程之间的 IPC 通信
 */
export class IPCHandlers {
  private database: DatabaseManager;
  private photoRepository: PhotoRepository;
  private fileScanner: FileScanner;
  private thumbnailGenerator: ThumbnailGenerator;
  private metadataExtractor: MetadataExtractor;
  private importTasks: Map<string, { abort: () => void }> = new Map();

  constructor() {
    this.database = new DatabaseManager();
    this.photoRepository = new PhotoRepository(this.database);
    this.fileScanner = new FileScanner();
    this.thumbnailGenerator = new ThumbnailGenerator();
    this.metadataExtractor = new MetadataExtractor();
  }

  /**
   * 注册所有 IPC 处理器
   */
  public registerHandlers(): void {
    this.registerAppHandlers();
    this.registerDialogHandlers();
    this.registerFileSystemHandlers();
    this.registerDatabaseHandlers();
    this.registerThumbnailHandlers();
    this.registerMetadataHandlers();
    this.registerImportHandlers();
    this.registerWindowHandlers();
    this.registerSystemHandlers();
  }

  /**
   * 注册应用相关处理器
   */
  private registerAppHandlers(): void {
    ipcMain.handle('app:getVersion', () => {
      return app.getVersion();
    });

    ipcMain.handle('app:getName', () => {
      return app.getName();
    });

    ipcMain.handle('app:getPath', (_, name: string) => {
      return app.getPath(name as any);
    });

    ipcMain.handle('app:quit', () => {
      app.quit();
    });
  }

  /**
   * 注册对话框相关处理器
   */
  private registerDialogHandlers(): void {
    ipcMain.handle('dialog:showOpenDialog', async (_, options) => {
      const result = await dialog.showOpenDialog(options);
      return result;
    });

    ipcMain.handle('dialog:showSaveDialog', async (_, options) => {
      const result = await dialog.showSaveDialog(options);
      return result;
    });

    ipcMain.handle('dialog:showMessageBox', async (_, options) => {
      const result = await dialog.showMessageBox(options);
      return result;
    });

    ipcMain.handle('dialog:showErrorBox', (_, title: string, content: string) => {
      dialog.showErrorBox(title, content);
    });

    // 添加缺失的 dialog:open-directory 处理器
    ipcMain.handle('dialog:open-directory', async (_, options?: any) => {
      try {
        const result = await dialog.showOpenDialog({
          title: '选择要导入的文件夹',
          properties: ['openDirectory', 'multiSelections'],
          message: '选择包含照片的文件夹',
          ...options
        });
        
        return {
          canceled: result.canceled,
          filePaths: result.filePaths
        };
      } catch (error) {
        console.error('打开目录对话框失败:', error);
        throw error;
      }
    });

    // 添加 show-message-box 处理器（与 showMessageBox 保持一致）
    ipcMain.handle('dialog:show-message-box', async (_, options) => {
      const result = await dialog.showMessageBox(options);
      return result;
    });

    // 添加 show-open-dialog 处理器（与 showOpenDialog 保持一致）
    ipcMain.handle('dialog:show-open-dialog', async (_, options) => {
      const result = await dialog.showOpenDialog(options);
      return result;
    });
  }

  /**
   * 注册文件系统相关处理器
   */
  private registerFileSystemHandlers(): void {
    ipcMain.handle('fs:exists', async (_, filePath: string) => {
      try {
        await fs.access(filePath);
        return true;
      } catch {
        return false;
      }
    });

    ipcMain.handle('fs:readFile', async (_, filePath: string) => {
      return await fs.readFile(filePath, 'utf-8');
    });

    ipcMain.handle('fs:writeFile', async (_, filePath: string, content: string) => {
      await fs.writeFile(filePath, content, 'utf-8');
    });

    ipcMain.handle('fs:mkdir', async (_, dirPath: string) => {
      await fs.mkdir(dirPath, { recursive: true });
    });

    ipcMain.handle('fs:readdir', async (_, dirPath: string) => {
      return await fs.readdir(dirPath);
    });

    ipcMain.handle('fs:stat', async (_, filePath: string) => {
      const stats = await fs.stat(filePath);
      return {
        size: stats.size,
        isFile: stats.isFile(),
        isDirectory: stats.isDirectory(),
        mtime: stats.mtime,
        ctime: stats.ctime,
        atime: stats.atime
      };
    });

    ipcMain.handle('fs:calculateHash', async (_, filePath: string) => {
      const buffer = await fs.readFile(filePath);
      return createHash('sha256').update(buffer).digest('hex');
    });

    ipcMain.handle('fs:showItemInFolder', (_, filePath: string) => {
      shell.showItemInFolder(filePath);
    });

    ipcMain.handle('fs:openPath', (_, filePath: string) => {
      return shell.openPath(filePath);
    });
  }

  /**
   * 注册数据库相关处理器
   */
  private registerDatabaseHandlers(): void {
    ipcMain.handle('db:init', async () => {
      await this.database.initialize();
    });

    ipcMain.handle('db:close', async () => {
      await this.database.close();
    });

    ipcMain.handle('db:query', async (_, sql: string, params?: any[]) => {
      return this.database.query(sql, params);
    });

    ipcMain.handle('db:execute', async (_, sql: string, params?: any[]) => {
      return this.database.execute(sql, params);
    });

    ipcMain.handle('db:transaction', async (_, operations: Array<{ sql: string; params?: any[] }>) => {
      return this.database.transaction(() => {
        const results = [];
        for (const op of operations) {
          results.push(this.database.execute(op.sql, op.params));
        }
        return results;
      });
    });

    ipcMain.handle('db:getStats', () => {
      // 返回基础统计信息
      return {
        connected: this.database.isConnected(),
        version: '1.0.0'
      };
    });

    ipcMain.handle('db:optimize', () => {
      this.database.optimize();
    });

    ipcMain.handle('db:backup', async (_, backupPath: string) => {
      await this.database.backup(backupPath);
    });

    // 应用层数据库操作
    ipcMain.handle('db:get-photos', async (_, options?: any) => {
      try {
        // TODO: 实现获取照片列表的逻辑
        console.log('获取照片列表:', options);
        return [];
      } catch (error) {
        console.error('获取照片列表失败:', error);
        throw error;
      }
    });

    ipcMain.handle('db:add-photo', async (_, photo: any) => {
      try {
        // TODO: 实现添加照片的逻辑
        console.log('添加照片:', photo);
        return { success: true, id: Date.now().toString() };
      } catch (error) {
        console.error('添加照片失败:', error);
        throw error;
      }
    });

    ipcMain.handle('db:update-photo', async (_, id: string, updates: any) => {
      try {
        // TODO: 实现更新照片的逻辑
        console.log('更新照片:', id, updates);
        return { success: true };
      } catch (error) {
        console.error('更新照片失败:', error);
        throw error;
      }
    });

    ipcMain.handle('db:delete-photo', async (_, id: string) => {
      try {
        // TODO: 实现删除照片的逻辑
        console.log('删除照片:', id);
        return { success: true };
      } catch (error) {
        console.error('删除照片失败:', error);
        throw error;
      }
    });

    ipcMain.handle('db:search-photos', async (_, query: string) => {
      try {
        // TODO: 实现搜索照片的逻辑
        console.log('搜索照片:', query);
        return [];
      } catch (error) {
        console.error('搜索照片失败:', error);
        throw error;
      }
    });

    ipcMain.handle('db:import-photos', async (_, photos: any[]) => {
      try {
        // TODO: 实现导入照片的逻辑
        console.log('导入照片:', photos.length);
        return { success: true, count: photos.length };
      } catch (error) {
        console.error('导入照片失败:', error);
        throw error;
      }
    });
  }

  /**
   * 注册缩略图相关处理器
   */
  private registerThumbnailHandlers(): void {
    ipcMain.handle('thumbnail:generate', async (_, imagePath: string, options?) => {
      return await this.thumbnailGenerator.generateThumbnail(imagePath, options);
    });

    ipcMain.handle('thumbnail:generateBatch', async (_, imagePaths: string[], options?) => {
      return await this.thumbnailGenerator.generateThumbnails(imagePaths, options);
    });

    ipcMain.handle('thumbnail:exists', async (_, imagePath: string, size?: 'small' | 'medium' | 'large') => {
      return await this.thumbnailGenerator.thumbnailExists(imagePath, size);
    });

    ipcMain.handle('thumbnail:delete', async (_, imagePath: string) => {
      await this.thumbnailGenerator.deleteThumbnail(imagePath);
    });

    ipcMain.handle('thumbnail:clear', async () => {
      await this.thumbnailGenerator.clearAllThumbnails();
    });

    ipcMain.handle('thumbnail:getStats', () => {
      // 返回缩略图统计信息
      return {
        totalThumbnails: 0,
        cacheSize: 0
      };
    });
  }

  /**
   * 注册元数据相关处理器
   */
  private registerMetadataHandlers(): void {
    ipcMain.handle('metadata:extract', async (_, imagePath: string, options?) => {
      return await this.metadataExtractor.extractMetadata(imagePath, options);
    });

    ipcMain.handle('metadata:extractBatch', async (_, imagePaths: string[], options?) => {
      // 批量提取元数据
      const results = [];
      for (const imagePath of imagePaths) {
        try {
          const metadata = await this.metadataExtractor.extractMetadata(imagePath, options);
          results.push({ imagePath, metadata, success: true });
        } catch (error) {
          results.push({ imagePath, error: (error as Error).message, success: false });
        }
      }
      return results;
    });

    ipcMain.handle('metadata:getBasicInfo', async (_, imagePath: string) => {
      // 获取基础图片信息
      try {
        const metadata = await this.metadataExtractor.extractMetadata(imagePath);
        return {
          width: metadata.width,
          height: metadata.height,
          orientation: metadata.orientation,
          colorSpace: metadata.colorSpace
        };
      } catch (error) {
        throw new Error(`无法获取图片基础信息: ${(error as Error).message}`);
      }
    });

    ipcMain.handle('metadata:getSupportedFormats', () => {
      return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'tiff', 'heic', 'heif'];
    });

    ipcMain.handle('metadata:isSupported', (_, filePath: string) => {
      const ext = filePath.toLowerCase().split('.').pop();
      const supportedFormats = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'tiff', 'heic', 'heif'];
      return supportedFormats.includes(ext || '');
    });
  }

  /**
   * 注册导入相关处理器
   */
  private registerImportHandlers(): void {
    // 添加缺失的 import:folders 处理器
    ipcMain.handle('import:folders', async (event, folderPaths: string[]) => {
      const taskId = this.generateTaskId();
      
      try {
        console.log('开始导入文件夹:', folderPaths);
        
        // 确保数据库已初始化
        if (!this.database.isConnected()) {
          console.log('数据库未连接，正在初始化...');
          await this.database.initialize();
        }
        
        let totalImported = 0;
        let allFiles: any[] = [];
        
        // 扫描所有文件夹
        for (const folderPath of folderPaths) {
          console.log('扫描文件夹:', folderPath);
          
          // 发送扫描进度
          event.sender.send('import:progress', {
            taskId,
            progress: {
              status: 'scanning',
              total: 0,
              current: 0,
              currentFile: `正在扫描: ${path.basename(folderPath)}`
            }
          });

          // 使用文件扫描器扫描目录
          const scanResult = await this.fileScanner.scanDirectory(folderPath, {
            recursive: true,
            generateHash: true,
            onProgress: (progress) => {
              event.sender.send('import:progress', {
                taskId,
                progress: {
                  status: 'scanning',
                  total: progress.totalFiles,
                  current: progress.processedFiles,
                  currentFile: progress.currentFile
                }
              });
            }
          });

          console.log(`扫描完成，找到 ${scanResult.files.length} 个图片文件`);
          allFiles.push(...scanResult.files);
        }

        console.log(`总共找到 ${allFiles.length} 个图片文件，开始导入...`);

        // 导入文件到数据库
        for (let i = 0; i < allFiles.length; i++) {
          const file = allFiles[i];
          
          // 发送导入进度
          event.sender.send('import:progress', {
            taskId,
            progress: {
              status: 'importing',
              total: allFiles.length,
              current: i + 1,
              currentFile: file.filename
            }
          });

          try {
            // 检查文件是否已存在（基于哈希去重）
            const existingPhoto = await this.photoRepository.getPhotoByHash(file.hash);
            if (existingPhoto) {
              console.log(`文件已存在，跳过: ${file.filename}`);
              continue;
            }

            // 生成缩略图
            const thumbnailInfo = await this.thumbnailGenerator.generateThumbnail(
              file.filepath,
              { size: 'medium', quality: 80 }
            );

            // 提取元数据
            const metadata = await this.metadataExtractor.extractMetadata(file.filepath);

            // 插入到数据库
            const photoData = {
              filename: file.filename,
              filepath: file.filepath,
              filesize: file.filesize,
              mimetype: file.mimetype,
              hash: file.hash,
              width: file.width || 0,
              height: file.height || 0,
              created_at: file.created_at || new Date().toISOString(),
              modified_at: file.modified_at || new Date().toISOString(),
              taken_at: metadata.dateTimeOriginal?.toISOString() || metadata.dateTime?.toISOString() || undefined,
              camera_make: metadata.make || undefined,
              camera_model: metadata.model || undefined,
              lens_model: metadata.lensModel || undefined,
              focal_length: metadata.focalLength || undefined,
              aperture: metadata.aperture || undefined,
              shutter_speed: metadata.shutterSpeedString || (metadata.shutterSpeed ? String(metadata.shutterSpeed) : undefined),
              iso: metadata.iso || undefined,
              flash: metadata.flash || false,
              white_balance: metadata.whiteBalance || undefined,
              latitude: metadata.latitude || undefined,
              longitude: metadata.longitude || undefined,
              altitude: metadata.altitude || undefined,
              location_name: undefined,
              orientation: metadata.orientation || undefined,
              color_space: metadata.colorSpace || undefined,
              description: metadata.description || undefined,
              keywords: metadata.keywords ? JSON.stringify(metadata.keywords) : undefined,
              copyright: metadata.copyright || undefined,
              artist: metadata.artist || undefined,
              software: metadata.software || undefined,
              favorite: false,
              rating: metadata.rating || 0,
              tags: '[]',
              thumbnail_generated: true,
              metadata_extracted: true,
              deleted: false,
              filehash: file.hash
            };

            await this.photoRepository.insertPhoto(photoData);
            totalImported++;
            
          } catch (error: unknown) {
            const errorMessage = error instanceof Error ? error.message : '未知错误';
            console.error(`导入文件失败: ${file.filename}`, errorMessage);
            // 继续处理下一个文件
          }
        }

        // 发送完成事件
        event.sender.send('import:progress', {
          taskId,
          progress: {
            status: 'completed',
            total: allFiles.length,
            current: allFiles.length,
            currentFile: `导入完成，成功导入 ${totalImported} 张照片`
          }
        });

        console.log(`导入完成，成功导入 ${totalImported} 张照片`);
        return { taskId, success: true, count: totalImported };
        
      } catch (error: any) {
        console.error('导入文件夹失败:', error);
        event.sender.send('import:error', { taskId, error: error.message });
        throw error;
      }
    });

    ipcMain.handle('import:scanFolder', async (event, folderPath: string, options?) => {
      const taskId = this.generateTaskId();
      
      try {
        const scanResult = await this.fileScanner.scanDirectory(folderPath, {
          ...options,
          onProgress: (progress) => {
            event.sender.send('import:progress', { taskId, progress });
          },
          onError: (error: any) => {
            event.sender.send('import:error', { taskId, error });
          }
        });

        // 存储中止函数（简化实现）
        this.importTasks.set(taskId, { abort: () => { /* 中止扫描 */ } });

        return { taskId, result: scanResult };
      } catch (error) {
        event.sender.send('import:error', { taskId, error });
        throw error;
      }
    });

    ipcMain.handle('import:abort', (_, taskId: string) => {
      const task = this.importTasks.get(taskId);
      if (task) {
        task.abort();
        this.importTasks.delete(taskId);
        return true;
      }
      return false;
    });

    ipcMain.handle('import:processFiles', async (event, files: string[], options?) => {
      const taskId = this.generateTaskId();
      
      try {
        // 处理文件导入逻辑
        const results = [];
        const total = files.length;
        
        for (let i = 0; i < files.length; i++) {
          const filePath = files[i];
          
          // 发送进度更新
          event.sender.send('import:progress', {
            taskId,
            progress: {
              current: i + 1,
              total,
              currentFile: filePath,
              phase: 'processing'
            }
          });

          try {
            // 提取元数据
            const metadata = await this.metadataExtractor.extractMetadata(filePath);
            
            // 生成缩略图
            const thumbnail = await this.thumbnailGenerator.generateThumbnail(filePath);
            
            // 计算文件哈希
            const hash = await this.calculateFileHash(filePath);
            
            results.push({
              filePath,
              metadata,
              thumbnail,
              hash,
              success: true
            });

            // 发送单个文件处理完成事件
            event.sender.send('photo:added', {
              filePath,
              metadata,
              thumbnail
            });

          } catch (error: unknown) {
            results.push({
              filePath,
              error: error instanceof Error ? error.message : String(error),
              success: false
            });

            event.sender.send('import:error', {
              taskId,
              error: {
                message: `处理文件失败: ${filePath}`,
                details: error instanceof Error ? error.message : String(error)
              }
            });
          }
        }

        return { taskId, results };
      } catch (error: unknown) {
        event.sender.send('import:error', { taskId, error });
        throw error;
      }
    });
  }

  /**
   * 注册窗口相关处理器
   */
  private registerWindowHandlers(): void {
    ipcMain.handle('window:minimize', () => {
      const window = BrowserWindow.getFocusedWindow();
      if (window) {
        window.minimize();
      }
    });

    ipcMain.handle('window:maximize', () => {
      const window = BrowserWindow.getFocusedWindow();
      if (window) {
        if (window.isMaximized()) {
          window.unmaximize();
        } else {
          window.maximize();
        }
      }
    });

    ipcMain.handle('window:close', () => {
      const window = BrowserWindow.getFocusedWindow();
      if (window) {
        window.close();
      }
    });

    ipcMain.handle('window:isMaximized', () => {
      const window = BrowserWindow.getFocusedWindow();
      return window ? window.isMaximized() : false;
    });

    ipcMain.handle('window:setFullScreen', (_, fullscreen: boolean) => {
      const window = BrowserWindow.getFocusedWindow();
      if (window) {
        window.setFullScreen(fullscreen);
      }
    });

    ipcMain.handle('window:isFullScreen', () => {
      const window = BrowserWindow.getFocusedWindow();
      return window ? window.isFullScreen() : false;
    });
  }

  /**
   * 注册系统相关处理器
   */
  private registerSystemHandlers(): void {
    ipcMain.handle('system:getPlatform', () => {
      return process.platform;
    });

    ipcMain.handle('system:getArch', () => {
      return process.arch;
    });

    ipcMain.handle('system:getVersion', () => {
      return process.version;
    });

    ipcMain.handle('system:getMemoryUsage', () => {
      return process.memoryUsage();
    });

    ipcMain.handle('system:getCPUUsage', () => {
      return process.cpuUsage();
    });
  }

  /**
   * 生成任务 ID
   */
  private generateTaskId(): string {
    return `task_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }

  /**
   * 计算文件哈希
   */
  private async calculateFileHash(filePath: string): Promise<string> {
    const buffer = await fs.readFile(filePath);
    return createHash('sha256').update(buffer).digest('hex');
  }

  /**
   * 清理资源
   */
  public async cleanup(): Promise<void> {
    // 中止所有进行中的任务
    for (const [taskId, task] of this.importTasks) {
      task.abort();
    }
    this.importTasks.clear();

    // 关闭数据库连接
    try {
      await this.database.close();
    } catch (error) {
      console.error('关闭数据库连接失败:', error);
    }
  }
}